package com.jeasonzhao.commons.data;

public class Range
{
    private int beginRowIndex = 0;
    private int endRowIndex = 0;
    private int beginColIndex = 0;
    private int endColIndex = 0;
    public Range()
    {
    }

    public Range(Position pStart)
    {
        this(pStart,null);
    }

    public Range(Position pStart,Position pEnd)
    {
        this(null==pStart?0:pStart.getRowIndex(),
             null==pStart?0:pStart.getColIndex(),
             null==pEnd?0:pEnd.getRowIndex(),
             null==pEnd?0:pEnd.getColIndex());
    }

    public Range(int beginR,int beginC,int endR,int endC)
    {
        this.beginRowIndex = beginR;
        this.beginColIndex = beginC;
        this.endRowIndex = endR;
        this.endColIndex = endC;
        adjust();
    }

    public Range createFromSpan(int beginR,int beginC,int rowSpan,int colSpan)
    {
        this.beginRowIndex = beginR;
        this.beginColIndex = beginC;
        this.setColSpan(colSpan);
        this.setRowSpan(rowSpan);
        return this;
    }

    private void adjust()
    {
        int n1 = this.beginRowIndex;
        int n2 = this.endRowIndex;
        this.beginRowIndex = Math.min(n1,n2);
        this.endRowIndex = Math.max(n1,n2);
        n1 = this.beginColIndex;
        n2 = this.endColIndex;
        this.beginColIndex = Math.min(n1,n2);
        this.endColIndex = Math.max(n1,n2);
    }

    public int getRowSpan()
    {
        int n = Math.abs(this.endRowIndex - this.beginRowIndex) + 1;
        return n < 2 ? 0 : n;
    }

    public int getColSpan()
    {
        int n = Math.abs(this.endColIndex - this.beginColIndex) + 1;
        return n < 2 ? 0 : n;
    }

    public int getBeginColIndex()
    {
        return beginColIndex;
    }

    public int getBeginRowIndex()
    {
        return beginRowIndex;
    }

    public int getEndColIndex()
    {
        return endColIndex;
    }

    public int getEndRowIndex()
    {
        return endRowIndex;
    }

    public Range setColSpan(int colSpan)
    {
        this.endColIndex = this.beginColIndex + (colSpan < 2 ? 0 : (colSpan - 1));
        return this;
    }

    public Range setRowSpan(int rowSpan)
    {
        this.endRowIndex = this.beginRowIndex + (rowSpan < 2 ? 0 : (rowSpan - 1));
        return this;
    }
    public Range startAt(Position p)
    {
        return startAt(null==p?0:p.getRowIndex(),null==p?0:p.getColIndex());
    }
    public Range startAt(int row,int col)
    {
        this.beginRowIndex = row;
        this.beginColIndex = col;
        return this;
    }

    public Range span(int rowSpan,int colSpan)
    {
        this.setRowSpan(rowSpan);
        this.setColSpan(colSpan);
        return this;
    }
    public Range endAt(Position p)
    {
        return endAt(null==p?0:p.getRowIndex(),null==p?0:p.getColIndex());
    }
    public Range endAt(int row,int col)
    {
        this.endRowIndex = row;
        this.endColIndex = col;
        adjust();
        return this;
    }

    public Range setEndRowIndex(int value)
    {
        this.endRowIndex = value;
        adjust();
        return this;
    }

    public Range setEndColIndex(int value)
    {
        this.endColIndex = value;
        adjust();
        return this;
    }

    public Range setBeginRowIndex(int value)
    {
        this.beginRowIndex = value;
        adjust();
        return this;
    }

    public Range setBeginColIndex(int value)
    {
        this.beginColIndex = value;
        adjust();
        return this;
    }

    public boolean contains(int nRowIndex,int nColIndex)
    {
        return beginRowIndex <= nRowIndex && endRowIndex >= nRowIndex &&
            beginColIndex <= nColIndex && endColIndex >= nColIndex;
    }

    public boolean isTopLeft(int nRowIndex,int nColIndex)
    {
        return beginRowIndex == nRowIndex && beginColIndex == nColIndex;
    }

}
